package com.lottery.service.qiuqiu.lobbyService;

import com.lottery.dao.qiuqiu.accoutDao.UserDao;
import com.lottery.dao.qiuqiu.lobbyDao.BettinginfoDao;
import com.lottery.dao.qiuqiu.lobbyDao.LotteryExchangeDao;
import com.lottery.dao.qiuqiu.lobbyDao.LotteryOddsDao;
import com.lottery.dao.qiuqiu.statisticsDao.AgencyDao;
import com.lottery.dao.qiuqiu.wealthDao.AccountDao;
import com.lottery.dao.qiuqiu.wealthDao.SystemCommissionDao;
import com.lottery.dto.AccountTransactionDto;
import com.lottery.dto.ResultDto;
import com.lottery.entity.*;
import com.lottery.initData.InitData;
import com.lottery.service.qiuqiu.JedisClient;
import com.lottery.service.qiuqiu.wealthService.WithdrawalsService;
import com.lottery.utils.DateUtil;
import com.lottery.utils.DealWithDouble;
import com.lottery.utils.RandCodeUtil;
import com.lottery.utils.lobbyUtils.impl.BjscPlayUtilImpl;
import com.lottery.utils.lobbyUtils.impl.SscPlayutilImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class LotteryExchangeService {
    @Autowired
    private JedisClient jedisClient;
    @Autowired
    private LotteryExchangeDao lotteryExchangeDao;

    @Autowired
    private LotteryOddsDao lotteryOddsDao;

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private BettinginfoDao bettinginfoDao;

    @Autowired
    private SystemCommissionDao systemCommissionDao;

    @Resource
    public WithdrawalsService withdrawalsService;

    @Resource
    private AgencyDao agencyDao;

    @Autowired
    private UserDao userDao;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 添加中奖信息到lottery_exchange表,并修改中奖状态,金额
     */
    @Transactional(rollbackFor = Exception.class)
    public ResultDto<LotteryExchange> insertLotteryExchange(Bettinginfo bettinginfo, String bet_way, int lotteryType)
            throws Exception {
        ResultDto<LotteryExchange> result = new ResultDto<LotteryExchange>();
        logger.debug("have win:{}", bet_way);
        try {
            LotteryExchange lotteryExchange = new LotteryExchange();
            // 获取对应的user_id
            int userId = bettinginfo.getUserId();
            lotteryExchange.setUserId(userId);
            lotteryExchange.setLotteryType(lotteryType);
            lotteryExchange.setBettinginfoId(bettinginfo.getId());
            lotteryExchange.setBettingrule(bettinginfo.getBettingrule());
            lotteryExchange.setPlaywayName(bettinginfo.getPlaywayName());
            lotteryExchange.setExpect(bettinginfo.getExpect());


            // 查询赔率表，获取赔率
            User user = userDao.selectId(userId);
            String betOdd ="";
            if(lotteryType == 1){
                betOdd =  SscPlayutilImpl.getSscBetOdd(bettinginfo.getPlaywayinfoId(), bet_way);
            }else if(lotteryType == 3){
                betOdd = BjscPlayUtilImpl.getSscBetOdd(bettinginfo.getPlaywayinfoId(), bet_way);
            }

            String agencyId = user.getAgencyId();
            if(agencyId.length()!=5){
                Agency agency = agencyDao.selectAgency(agencyId);
                agencyId=agency.getProxyRefAgency()+"";
            }
            double odds = InitData.LOTTEY_REF_LOTTEYODD.get(lotteryType).get(agencyId).get(bettinginfo.getPlaywayinfoId()).get(betOdd).getOdds();


            // 查询分成比例
            //Double selectLotteryOddsRatio = lotteryOddsDao.selectLotteryOddsRatio();
            // 中奖金额=投注金额 * 赔率
            double Winningamount = DealWithDouble.mul(bettinginfo.getBettingmoney(), odds, 2, 4);
            lotteryExchange.setWinningamount(Winningamount);
            // 返回金额=中奖金额
            double returnMoney = Winningamount;

            // 查询原有的账户余额
            Account account = accountDao.selectAccountByUserId(userId);

            // 中奖金额账户流水
            AccountTransactionDto accountTransactionDto = new AccountTransactionDto();
            accountTransactionDto.setUserId(userId);
            accountTransactionDto.setMoneySources("中奖");
            accountTransactionDto.setTransactionMoney(returnMoney);
            accountTransactionDto.setTransactionType(4);
            accountTransactionDto.setState(1);
            accountTransactionDto.setOrderId(RandCodeUtil.getOrderId());
            accountTransactionDto.setRemarks("["+bettinginfo.getPlaywayName()+"]期号[" + bettinginfo.getExpect() + "]竞猜["+bettinginfo.getBettingrule()+"]");
            accountTransactionDto.setCashAccount(DealWithDouble.sum(account.getAccountFunds(), returnMoney, 2, 4));
            withdrawalsService.insertAccountTransactionDto(accountTransactionDto);


            // 返回金额添加到账户余额
            account.setAccountFunds(DealWithDouble.sum(account.getAccountFunds(), returnMoney, 2, 4));
            int updateNum = accountDao.updateAccountMoneyById(account);
            if (updateNum == 0) {
                result.setSuccess(false);
                result.setMessage("添加失败");
                return result;
            }else{

            }
            // 修改中奖状态,默认未开奖
            Bettinginfo bettinginfo1 = new Bettinginfo();
            bettinginfo1.setId(bettinginfo.getId());
            bettinginfo1.setState(1);
            double sub = DealWithDouble.sub(returnMoney, bettinginfo.getBettingmoney(), 2, 4);
            bettinginfo1.setAccountChange(sub);
            Account zz = accountDao.selectAccountByUserId(userId);
            //accountMoney = DealWithDouble.sum(accountMoney,sub,2,4);
            //result.setData2(accountMoney);
            //bettinginfo1.setAccountMoney(accountMoney);
            bettinginfo1.setAccountMoney(zz.getAccountFunds());
            bettinginfo1.setRemark("期号[" + bettinginfo.getExpect() + "]竞猜中奖了");
            bettinginfoDao.updateBettinginfo(bettinginfo1);


            // 添加到开奖表
            lotteryExchangeDao.insertLotteryExchange(lotteryExchange);
            result.setSuccess(true);
            result.setMessage("添加成功！");

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("insertLotteryExchange error:", e);
            result.setSuccess(false);
            result.setMessage("添加失败！");
            throw new Exception("添加失败");
        }

        return result;
    }

    /**
     * 分享用户比例分成
     */

    @Transactional(rollbackFor = Exception.class)
    public ResultDto<LotteryExchange> UserRateSharing(String expect, int lotteryType) throws Exception {
        ResultDto<LotteryExchange> result = new ResultDto<LotteryExchange>();
        try {
            // 查询中奖信息
            List<LotteryExchange> list = lotteryExchangeDao.selectLotteryExchangeList(expect, lotteryType);
            logger.info("用户比例分成yonghubili {}={}", lotteryType, list);
            // 判断中奖信息是否为空
            if (list == null || list.size() <= 0) {
                result.setSuccess(true);
                result.setMessage("没有中奖的用户！");
                logger.info("用户比例分成yonghubili={}", "没有中奖的用户！");
                return result;
            }
            for (LotteryExchange lotteryExchange : list) {

                String playwayName = lotteryExchange.getPlaywayName();

                int userId = lotteryExchange.getUserId();
                // 通过玩法查询分成比例
                LotteryOdds lottery = new LotteryOdds();
                lottery.setPlaywayName(playwayName);
                lottery.setLotteyType(lotteryType);
                List<LotteryOdds> lotteryOdds = lotteryOddsDao.selectLotteryOddsByPlaywayName(lottery);
                double ratio = lotteryOdds.get(0).getRatio();
                double winningamount = lotteryExchange.getWinningamount() / (1 - ratio);
                // 获取分成的金额
                double money = ratio * winningamount;
                DecimalFormat df = new DecimalFormat("#0.##");
                df.setRoundingMode(RoundingMode.FLOOR);
                money = Double.valueOf(df.format(money));
                // 通过中奖用户的userId获得推荐码
                String RecommendCode = userDao.selectId(userId).getRecommendCode();
                if (RecommendCode == null || RecommendCode.length() == 0) {
                    logger.info("system Recommend......");
                    SystemCommission systemCommission = new SystemCommission();
                    systemCommission.setTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
                    systemCommission.setCommissionMoney(money);
                    systemCommission.setUserId(userId);
                    systemCommissionDao.insertSystemCommission(systemCommission);
                    continue;
                }
                // 通过推荐码获得推荐人的id
                int recommendId = userDao.selectByMyRecommendCode(RecommendCode).getUserId();

                // 查询推荐人的账户余额
                // Account account =
                // accountDao.selectAccountByUserId(recommendId);
                // double account_funds = account.getAccountFunds();
                // 构建新的实例
                Account account1 = new Account();
                // 分成金额添加到账户余额
                account1.setUserId(recommendId);
                // account1.setAccountFunds(account_funds + money);
                // accountDao.updateAccount(account1);

                account1.setAccountFunds(money);
                int updateNum = accountDao.addAccount(account1);
                if (updateNum == 0) {
                    result.setSuccess(false);
                    result.setMessage("金额分成失败");
                    logger.info("用户比例分成yonghubili={}", "金额分成失败,跟新金额失败");
                    return result;
                }

                // 分成金额账户流水
                AccountTransactionDto accountTransactionDto = new AccountTransactionDto();
                accountTransactionDto.setUserId(recommendId);
                accountTransactionDto.setMoneySources("推荐分成");
                accountTransactionDto.setTransactionMoney(money);
                accountTransactionDto.setExpect(expect);
                accountTransactionDto.setTransactionType(5);
                accountTransactionDto.setState(1);
                accountTransactionDto.setOrderId(RandCodeUtil.getOrderId());
                withdrawalsService.insertAccountTransactionDto(accountTransactionDto);

            }
            result.setSuccess(true);
            result.setMessage("金额分成成功！");
        } catch (Exception e) {
            result.setSuccess(true);
            logger.error("用户比例分成yonghubili={}", "金额分成失败,分成金额账户流水失败", e);
            result.setMessage("金额分成失败！");
            throw new Exception("金额分成失败");
        }

        return result;
    }


    public LotteryExchange robotLotteryExchange(Bettinginfo bettinginfo, String betWay, int lotteyType) {
        LotteryExchange lotteryExchange = new LotteryExchange();
        try {
            // 获取对应的user_id
            int userId = bettinginfo.getUserId();
            lotteryExchange.setUserId(userId);
            lotteryExchange.setBettinginfoId(bettinginfo.getId());
            lotteryExchange.setBettingrule(bettinginfo.getBettingrule());
            lotteryExchange.setPlaywayName(bettinginfo.getPlaywayName());
            lotteryExchange.setExpect(bettinginfo.getExpect());
            // 查询赔率表，获取赔率
            Map<String, Object> params = new HashMap<>();
            params.put("bet_way", betWay);
            params.put("lotteyType", lotteyType);
            LotteryOdds lotteryOdds = lotteryOddsDao.selectLotteryOdds(params);
            double odds = lotteryOdds.getOdds();
            // 查询分成比例
            Double selectLotteryOddsRatio = lotteryOddsDao.selectLotteryOddsRatio();
            // 中奖金额=投注金额 * 赔率*(1-分成比例)
            double Winningamount = bettinginfo.getBettingmoney() * odds * (1 - selectLotteryOddsRatio);
            lotteryExchange.setWinningamount(Winningamount);

            // double am = Double.parseDouble(jedisClient.hget(userId + "",
            // "amount"));
            // double bala = am + Winningamount + bettinginfo.getBettingmoney();
            // jedisClient.hset(userId + "", "amount", bala + "");

        } catch (Exception e) {
            logger.error("robotLotteryExchange error:", e);
            return null;
        }
        return lotteryExchange;
    }


    public LotteryExchange touristLotteryExchange(Bettinginfo bettinginfo, String betWay, int lotteyType) {
        LotteryExchange lotteryExchange = new LotteryExchange();
        try {
            // 获取对应的user_id
            int userId = bettinginfo.getUserId();
            lotteryExchange.setUserId(userId);
            lotteryExchange.setBettinginfoId(bettinginfo.getBettingnumber());
            lotteryExchange.setBettingrule(bettinginfo.getBettingrule());
            lotteryExchange.setPlaywayName(bettinginfo.getPlaywayName());
            lotteryExchange.setExpect(bettinginfo.getExpect());
            lotteryExchange.setLotteryType(lotteyType);
            // 查询赔率表，获取赔率
            Map<String, Object> params = new HashMap<>();
            params.put("bet_way", betWay);
            params.put("lotteyType", lotteyType);
            LotteryOdds lotteryOdds = lotteryOddsDao.selectLotteryOdds(params);
            double odds = lotteryOdds.getOdds();
            // 查询分成比例
            Double selectLotteryOddsRatio = lotteryOddsDao.selectLotteryOddsRatio();
            // 中奖金额=投注金额 * 赔率*(1-分成比例)
            double Winningamount = bettinginfo.getBettingmoney() * odds * (1 - selectLotteryOddsRatio);
            lotteryExchange.setWinningamount(Winningamount);

            double am = Double.parseDouble(jedisClient.hget(userId + "", "amount"));
            double bala = am + Winningamount + bettinginfo.getBettingmoney();
            jedisClient.hset(userId + "", "amount", bala + "");

        } catch (Exception e) {
            return null;
        }
        return lotteryExchange;
    }

    /**
     * 分割汉字和数字
     */
    private static String Division(String s) {

        Pattern p = Pattern.compile("[\\u4e00-\\u9fa5]+|\\d+");
        Matcher m = p.matcher(s);
        String group = "";
        if (m.find()) {
            group = m.group();
        }
        return group;
    }

}
